package tr.edu.metu.is.mega.client.course.admin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import tr.edu.metu.is.mega.client.core.EditDialog;
import tr.edu.metu.is.mega.client.resource.MEGAResourceBundle;
import tr.edu.metu.is.mega.client.resource.MEGAResources;
import tr.edu.metu.is.mega.client.user.UserField;
import tr.edu.metu.is.mega.client.widgets.MegaTextField;
import tr.edu.metu.is.mega.common.dto.CourseAssistantDTO;
import tr.edu.metu.is.mega.common.dto.CourseDTO;
import tr.edu.metu.is.mega.common.dto.UserDTO;
import tr.edu.metu.is.mega.common.dto.UserRole;

import com.extjs.gxt.ui.client.binding.FormBinding;
import com.extjs.gxt.ui.client.binding.SimpleComboBoxFieldBinding;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.layout.FormData;

/**
 * Main window to manage course definitions.
 */
public class CourseDefinitionDialog extends EditDialog<CourseDTO> {

    private MegaTextField textFieldCourseCode;

    private MegaTextField textFieldName;

    private FormBinding formBinding;

    private BeanModelFactory modelFactoryCourse;

    private UserField instructorField;

    private UserField assistantsField;

    private MEGAResourceBundle resourceBundle = MEGAResources.RESOURCEBUNDLE;

    private HashMap<Integer, Integer> assistantIdMap;

    /**
     * Default constructor.
     */
    public CourseDefinitionDialog() {
        super(CourseDTO.class.getName());
        setHeading(resourceBundle.courseDefinitionDialogHeader());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void initForm(FormPanel parent, Object... params) {
        modelFactoryCourse = BeanModelLookup.get().getFactory(CourseDTO.class);
        resourceBundle = MEGAResources.RESOURCEBUNDLE;
        assistantIdMap = new HashMap<Integer, Integer>();
        textFieldCourseCode = new MegaTextField(CourseDTO.FIELD_CODE);
        textFieldCourseCode.setFieldLabel(resourceBundle.courseCode());
        parent.add(textFieldCourseCode, new FormData("96%"));

        textFieldName = new MegaTextField(CourseDTO.FIELD_NAME);
        textFieldName.setFieldLabel(resourceBundle.courseName());
        parent.add(textFieldName, new FormData("96%"));

        SimpleComboBox<String> comboBox = createRoleComboBox(CourseDTO.FIELD_SEMESTER);
        parent.add(comboBox, new FormData("70%"));

        instructorField = new UserField(CourseDTO.FIELD_INSTRUCTOR, false, true, UserRole.INSTRUCTOR);
        instructorField.setFieldLabel(resourceBundle.courseInstructor());

        parent.add(instructorField, new FormData("96%"));

        assistantsField = new UserField(CourseDTO.FIELD_ASSISTANTS, true, true, UserRole.ASSISTANT);
        assistantsField.setFieldLabel(resourceBundle.courseAssistants());

        parent.add(assistantsField, new FormData("96%"));

        formBinding = new FormBinding(parent);

        formBinding.addFieldBinding(new SimpleComboBoxFieldBinding(comboBox, CourseDTO.FIELD_SEMESTER));

        formBinding.autoBind();

        formBinding.bind(modelFactoryCourse.createModel(new CourseDTO()));

        setSize(350, 220);
    }

    /**
     * Creates role combobox and binds it.
     * 
     * @param boundAttribute attribute to bind
     * @return created role combobox
     */
    public static SimpleComboBox<String> createRoleComboBox(String boundAttribute) {
        SimpleComboBox<String> combo = new SimpleComboBox<String>();
        combo.setFieldLabel("Semester");
        combo.add("2012 Spring");
        combo.add("2011 Fall");
        combo.add("2010 Spring");
        return combo;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void dtoToGUI(CourseDTO dto) {
        instructorField.setValue(dto.getInstructor());
        assistantIdMap = new HashMap<Integer, Integer>(dto.getAssistants().size());
        List<UserDTO> assistants = new ArrayList<UserDTO>(dto.getAssistants().size());
        for (CourseAssistantDTO dto2 : dto.getAssistants()) {
            assistants.add(dto2.getUser());
            assistantIdMap.put(dto2.getUser().getPkid(), dto2.getPkid());
        }
        assistantsField.setValue(assistants);
        formBinding.bind(modelFactoryCourse.createModel(dto));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected CourseDTO guiToDTO() {
        BeanModel model = (BeanModel) formBinding.getModel();
        CourseDTO dto = model.getBean();
        dto.setInstructor((UserDTO) instructorField.getValue());
        @SuppressWarnings("unchecked")
        List<UserDTO> users = (List<UserDTO>) assistantsField.getValue();
        if (users != null) {
            List<CourseAssistantDTO> assistantDTOs = new ArrayList<CourseAssistantDTO>(users.size());
            for (UserDTO userDTO : users) {
                CourseAssistantDTO assistantDTO = new CourseAssistantDTO();
                assistantDTO.setPkid(assistantIdMap.get(userDTO.getPkid()));
                assistantDTO.setCourse(dto);
                assistantDTO.setUser(userDTO);
                assistantDTOs.add(assistantDTO);
            }
            dto.setAssistants(assistantDTOs);
        }
        return dto;
    }
}
